package com.william.jdbcplus.core.meta;

import com.william.jdbcplus.common.annotation.TableColumn;
import com.william.jdbcplus.common.annotation.TableLogic;
import com.william.jdbcplus.common.enums.FillType;
import com.william.jdbcplus.core.property.JdbcPlusProperties;
import com.william.jdbcplus.core.toolkit.Constants;
import com.william.jdbcplus.core.toolkit.StringUtil;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.ToString;

import java.lang.reflect.Field;

/**
 * 数据库表字段反射信息
 */
@Getter
@ToString
@EqualsAndHashCode
public class TableColumnInfo implements Constants {

    /**
     * 表名
     */
    private final String tableName;

    /**
     * 字段名
     */
    private final String column;

    /**
     * 是否可空
     */
    private final boolean nullable;

    /**
     * 字段描述
     */
    private final String remarks;

    /**
     * 列长度
     */
    private final int size;

    /**
     * 小数位数
     */
    private final int digits;

    /**
     * 属性名
     */
    private final String property;

    /**
     * 属性类型
     */
    private final Class<?> propertyType;

    /**
     * 字段填充类型
     */
    private final FillType fillType;

    /**
     * 逻辑删除值
     */
    private String logicDeleteValue;

    /**
     * 逻辑未删除值
     */
    private String logicNotDeleteValue;

    public TableColumnInfo(TableColumnInfo columnInfo, String newColumn) {
        this.tableName = columnInfo.tableName;
        this.property = columnInfo.property;
        this.propertyType = columnInfo.propertyType;
        this.column = newColumn;
        this.size = columnInfo.size;
        //新字段必须可空，防止报错
        this.nullable = true;
        this.remarks = columnInfo.remarks;
        this.digits = columnInfo.digits;
        this.fillType = columnInfo.fillType;
    }

    public TableColumnInfo(TableInfo tableInfo, Field field) {
        this.tableName = tableInfo.getTableName();
        this.property = field.getName();
        this.propertyType = field.getType();
        tableInfo.setLogicDelete(this.initLogicDelete(field));
        this.column = JdbcPlusProperties.isColumnUnderline() ? StringUtil.humpToUnderline(field.getName()) : field.getName();
        this.size = 50;
        this.nullable = true;
        this.remarks = field.getName();
        this.digits = 0;
        this.fillType = FillType.INPUT;
    }

    public TableColumnInfo(TableInfo tableInfo, Field field, TableColumn tableColumn) {
        this.tableName = tableInfo.getTableName();
        this.property = field.getName();
        this.propertyType = field.getType();
        tableInfo.setLogicDelete(this.initLogicDelete(field));
        String defaultColumn = JdbcPlusProperties.isColumnUnderline() ? StringUtil.humpToUnderline(field.getName()) : field.getName();
        this.column = StringUtil.isNotBlank(tableColumn.value()) ? tableColumn.value() : defaultColumn;
        this.size = tableColumn.size();
        this.nullable = tableColumn.nullable();
        this.remarks = StringUtil.isBlank(tableColumn.remarks()) ? tableColumn.value() : tableColumn.remarks();
        this.digits = tableColumn.digits();
        this.fillType = tableColumn.fillType();
    }

    /**
     * 逻辑删除初始化
     *
     * @param field 字段属性对象
     */
    private boolean initLogicDelete(Field field) {
        /* 获取注解属性，逻辑处理字段 */
        TableLogic tableLogic = field.getAnnotation(TableLogic.class);
        if (null != tableLogic) {
            if (StringUtil.isNotBlank(tableLogic.value())) {
                this.logicNotDeleteValue = tableLogic.value();
            } else {
                this.logicNotDeleteValue = "0";
            }
            if (StringUtil.isNotBlank(tableLogic.delVal())) {
                this.logicDeleteValue = tableLogic.delVal();
            } else {
                this.logicDeleteValue = "1";
            }
            return true;
        }
        return false;
    }

    /**
     * 是否注解了逻辑删除
     */
    public boolean isLogicDelete() {
        return StringUtil.isNotBlank(logicDeleteValue);
    }

}
